home *** CD-ROM | disk | FTP | other *** search
- /* SQLWindow.m:
- * You may freely copy, distribute, and reuse the code in this example.
- * NeXT disclaims any warranty of any kind, expressed or implied, as to its
- * fitness for any particular use.
- *
- * Written by Jack Greenfield
- *
- */
-
- #import "ScrollViewExtras.h"
- #import "SQLWindow.h"
- #import "MultiBinder.h"
-
- #define FAILURE NXLocalizedString("Failure:", NULL, \
- "Message given to user when an operation has failed.")
-
- #define CANNOT_CONNECT NXLocalizedString("Cannot connect to database", NULL, \
- "Message given to user to explain what fails. ")
-
- #define OK NXLocalizedString("OK", NULL, "Okay to continue ")
-
- @implementation SQLWindow
-
- - free
- {
- [database free];
- return [super free];
- }
-
- - initWithFile:(const char *)filename
- {
- char path[MAXPATHLEN];
-
- if ((self = [super init]) != nil)
- {
- database = [[DBDatabase alloc] initFromFile:filename];
- if (![database connect])
- {
- NXRunAlertPanel(FAILURE, CANNOT_CONNECT, OK, NULL, NULL);
- return [self free];
- }
-
- [[NXBundle mainBundle] getPath:path forResource:"SQLWindow" ofType:"nib"];
- [NXApp loadNibFile:path owner:self withNames:NO];
- [[resultsView window] setDelegate:self];
- [[resultsView window] setTitleAsFilename:filename];
- [[queryView docView] selectAll:self];
- [[resultsView window] makeKeyAndOrderFront:self];
- }
-
- return self;
- }
-
- - database { return database; }
-
- - evaluate:sender
- {
- int charCount;
- char *buffer;
- MultiBinder *binder;
- id <DBContainers> rowsList;
-
- if ((charCount = [[queryView docView] textLength]) > 0)
- {
- binder = [[MultiBinder alloc] initFromPropertyLists:nil];
- [binder setDatabase:database];
- [binder setDelegate:self];
- rowsList = [[List alloc] init];
- [binder setContainer: rowsList];
-
- buffer = (char *) alloca(1 + charCount);
- [[queryView docView] getSubstring:buffer start:0 length:charCount];
- buffer[charCount] = 0;
- while (charCount > 0 && buffer[--charCount] == '\n')
- buffer[charCount] = 0;
-
- [resultsView sprintf:"%s\n", buffer];
- if (![binder evaluateString:buffer])
- [resultsView sprintf:"EVALUATION FAILED\n\n"];
- else
- if (![binder fetch])
- [resultsView sprintf:"FETCH FAILED\n\n"];
- else
- /* For the last result set, binderWillChangeResultSet
- * needs to be called explicitly.
- */
- [self binderWillChangeResultSet:binder];
-
- [resultsView sprintf:"\n"];
- [binder free];
- [(List *)rowsList free];
- }
-
- [[queryView docView] selectText:self];
- return self;
- }
-
- - clear:sender
- {
- [resultsView clear:sender];
- [[queryView docView] selectText:self];
- return self;
- }
-
- - print:sender
- {
- [resultsView print:sender];
- [[queryView docView] selectText:self];
- return self;
- }
-
- /* This delegate method will be called every time a new result set is being
- * fetched. All objects returned by the binder fetch can be retrieved from the
- * binder container (named rowsList here). Note that the container will get
- * flushed everytime a new result set is retrieved. This delegate method is the
- * place where you can save the result set elsewhere if needed.
- */
- - binderWillChangeResultSet:(MultiBinder *)binder
- {
- int rowsIndex;
- int rowsCount;
- int propIndex;
- int propCount;
- List *rowsList;
- List *propList;
-
- propList = [[List alloc] init];
- [binder getCurrentProperties:propList];
- rowsList = binder->container; // public instance variable!!!
- rowsCount = [rowsList count];
- [resultsView sprintf:"\nresult set %d\n", [binder currentResultSet]];
- [resultsView sprintf:"%u records selected\n", rowsCount];
- [binder setFirst];
- for (rowsIndex = 0; rowsIndex < rowsCount; ++rowsIndex)
- {
- propCount = [propList count];
- for (propIndex = 0; propIndex < propCount; ++propIndex)
- {
- id p = [propList objectAt:propIndex];
- [resultsView sprintf:"%s=(%s) ",
- [p name], [[binder valueForProperty:p] stringValue]];
- }
-
- [resultsView sprintf:"\n"];
- [binder setNext];
- }
-
- [propList free];
- return self;
- }
-
- @end
-